Sensor Fusion for Kinetis MCUs (ISSDK/KSDK version)
main_freertos_single_task.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016, NXP Semiconductor, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * o Redistributions of source code must retain the above copyright notice, this list
9  * of conditions and the following disclaimer.
10  *
11  * o Redistributions in binary form must reproduce the above copyright notice, this
12  * list of conditions and the following disclaimer in the documentation and/or
13  * other materials provided with the distribution.
14  *
15  * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
16  * contributors may be used to endorse or promote products derived from this
17  * software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 /*! \file main_freertos_single_task.c
31  \brief FreeRTOS (single task) implementation of sensor fusion on FRDM-K64F.
32 
33  This file shows one recommended way to incorporate sensor fusion capabilities
34  into a FreeRTOS project.
35 */
36 
37 /* FreeRTOS kernel includes. */
38 #include "FreeRTOS.h"
39 #include "task.h"
40 #include "queue.h"
41 #include "timers.h"
42 #include "event_groups.h"
43 
44 // ISSDK Headers
45 #include "fxls8471q.h"
46 #include "mag3110.h"
47 #include "fxas21002.h"
48 #include "mpl3115.h"
49 #include "mma865x.h"
50 #include "fxos8700.h"
51 #include "mma9553.h"
52 
53 // KSDK Headers
54 #include "fsl_debug_console.h" // KSDK header file for the debug interface
55 #include "board.h" // KSDK header file to define board configuration
56 #include "pin_mux.h" // KSDK header file for pin mux initialization functions
57 #include "clock_config.h" // KSDK header file for clock configuration
58 #include "fsl_port.h" // KSDK header file for Port I/O control
59 #include "fsl_i2c.h" // KSDK header file for I2C interfaces
60 
61 // Sensor Fusion Headers
62 #include "sensor_fusion.h" // top level magCal and sensor fusion interfaces
63 #include "hal.h" // Hardware Abstraction Layer board dependencies beyond those generated in board.h by PEX
64 #include "control.h" // Command/Streaming interface - application specific
65 #include "status.h" // Status indicator interface - application specific
66 #include "drivers.h" // NXP sensor drivers OR customer-supplied drivers
67 #include "driver_pit.h" // Project-specific - PIT is used to control main() timing loop
68 
69 // Global data structures
70 SensorFusionGlobals sfg; ///< This is the primary sensor fusion data structure
71 ControlSubsystem controlSubsystem; ///< used for serial communications
72 StatusSubsystem statusSubsystem; ///< provides visual (usually LED) status indicator
73 PhysicalSensor sensors[2]; ///< This implementation uses two physical sensors
74 EventGroupHandle_t event_group = NULL;
75 
76 // externals
77 extern uint8_t sUARTOutputBuffer[256]; ///< main output buffer defined in control.c
78 extern ARM_DRIVER_I2C Driver_I2C1_KSDK2_Blocking; ///< KSDK handle for the I2C port defined in Driver_I2C_KSDK2.
79 #define I2C_DRIVER Driver_I2C1_KSDK2_Blocking
80 
81 /// Dummy callback function for the I2C driver
82 void myI2C_callback(uint32_t event)
83 {
84  // Only needs to be present
85 }
86 static void read_task(void *pvParameters);
87 
88 ARM_DRIVER_I2C* I2Cdrv = &I2C_DRIVER; ///< KSDK handle for the I2C port defined in Driver_I2C_KSDK2.c
89 
90 /// This is a FreeRTOS (single task) implementation of the NXP sensor fusion demo build.
91 int main(void)
92 {
93  BOARD_InitPins(); // defined in pin_mux.c, initializes pkg pins
94  BOARD_BootClockRUN(); // defined in clock_config.c, initializes clocks
95  BOARD_InitDebugConsole(); // defined in board.c, initializes the OpenSDA port
96 
97  I2Cdrv->Initialize(myI2C_callback); // Initialize the KSDK driver for the I2C port
98  CLOCK_EnableClock(I2C_PORT_CLKEN); // You must ewnable a port's clock before configuring it
99  PORT_SetPinMux(I2C_PORT, I2C_SDA_PIN, I2C_MUX); // Configure the SDA pin muxing
100  PORT_SetPinMux(I2C_PORT, I2C_SCL_PIN, I2C_MUX); // Configure the SCL pin muxing
101  CLOCK_EnableClock(I2C_CLKEN); // Enable the clock for the I2C module
102  I2C_DRIVER.Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_FAST); // Configure the I2C bus speed
103 
104  initializeControlPort(&controlSubsystem); // configure pins and ports for the control sub-system
105  initializeStatusSubsystem(&statusSubsystem); // configure pins and ports for the status sub-system
106  initSensorFusionGlobals(&sfg, &statusSubsystem, &controlSubsystem); // Initialize sensor fusion structures
107  // "install" the sensors we will be using
108  sfg.installSensor(&sfg, &sensors[0], F_ALL_SENSORS, 0x1E, 1, (void*) I2Cdrv, FXOS8700_Init, FXOS8700_Read);
109  sfg.installSensor(&sfg, &sensors[1], F_ALL_SENSORS, 0x20, 1, (void*) I2Cdrv, FXAS21002_Init, FXAS21002_Read);
110  sfg.initializeFusionEngine(&sfg); // This will initialize sensors and magnetic calibration
111 
112  event_group = xEventGroupCreate();
113  xTaskCreate(read_task, "READ_TASK", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);
114  sfg.setStatus(&sfg, NORMAL); // If we got this far, let's set status state to NORMAL
115  /* Start scheduling. */
116  vTaskStartScheduler();
117  for (;;) ;
118 }
119 
120 static void read_task(void *pvParameters)
121 {
122  uint16_t i=0; // general counter variable
123  portTickType lastWakeTime;
124  const portTickType frequency = 10;
125  lastWakeTime = xTaskGetTickCount();
126  while (1)
127  {
128  vTaskDelayUntil(&lastWakeTime, frequency);
129  GPIO_TogglePinsOutput(GPIOB, 1U << 9U); // toggle GPIO pin to check freq - DEBUG ONLY
130 
131  sfg.readSensors(&sfg, 1); // Reads sensors, applies HAL and does averaging (if applicable)
132  sfg.runFusion(&sfg); // Run the actual fusion algorithms
133  sfg.applyPerturbation(&sfg); // apply debug perturbation (testing only)
134  sfg.loopcounter++; // The loop counter is used to "serialize" mag cal operations
135  i=i+1;
136  if (i>=4) { // Some status codes include a "blink" feature. This loop
137  i=0; // should cycle at least four times for that to operate correctly.
138  sfg.updateStatus(&sfg); // This is where pending status updates are made visible
139  }
140  sfg.queueStatus(&sfg, NORMAL); // assume NORMAL status for next pass through the loop
141  sfg.pControlSubsystem->stream(&sfg, sUARTOutputBuffer); // Send stream data to the Sensor Fusion Toolbox
142  }
143 }
144 
145 /// \endcode
void initSensorFusionGlobals(SensorFusionGlobals *sfg, StatusSubsystem *pStatusSubsystem, ControlSubsystem *pControlSubsystem)
utility function to insert default values in the top level structure
Definition: sensor_fusion.c:68
ControlSubsystem controlSubsystem
used for serial communications
int32_t loopcounter
counter incrementing each iteration of sensor fusion (typically 25Hz)
static void read_task(void *pvParameters)
#define F_ALL_SENSORS
int main(void)
This is a FreeRTOS (single task) implementation of the NXP sensor fusion demo build.
int8_t FXOS8700_Read(PhysicalSensor *sensor, SensorFusionGlobals *sfg)
void initializeStatusSubsystem(StatusSubsystem *pStatus)
initializeStatusSubsystem() should be called once at startup to initialize the data structure and to ...
Definition: status.c:185
The top level fusion structure.
streamData_t * stream
function to create packets for serial stream
Definition: control.h:73
#define I2C_DRIVER
installSensor_t * installSensor
function for installing a new sensor into t
StatusSubsystem() provides an object-like interface for communicating status to the user...
Definition: status.h:44
readSensors_t * readSensors
read all physical sensors
struct ControlSubsystem * pControlSubsystem
initializeFusionEngine_t * initializeFusionEngine
set sensor fusion structures to initial values
updateStatus_t * updateStatus
status=next status
int8_t FXOS8700_Init(PhysicalSensor *sensor, SensorFusionGlobals *sfg)
SensorFusionGlobals sfg
This is the primary sensor fusion data structure.
int8_t FXAS21002_Read(PhysicalSensor *sensor, SensorFusionGlobals *sfg)
void myI2C_callback(uint32_t event)
Dummy callback function for the I2C driver.
The sensor_fusion.h file implements the top level programming interface.
Provides function prototypes for driver level interfaces.
he ControlSubsystem encapsulates command and data streaming functions.
Definition: control.h:64
int8_t initializeControlPort(ControlSubsystem *pComm)
Initialize the control subsystem and all related hardware.
Definition: control.c:182
runFusion_t * runFusion
run the fusion routines
Provides a simple abstraction for a periodic interval timer.
ARM_DRIVER_I2C * I2Cdrv
KSDK handle for the I2C port defined in Driver_I2C_KSDK2.c.
Application-specific status subsystem.
An instance of PhysicalSensor structure type should be allocated for each physical sensors (combo dev...
EventGroupHandle_t event_group
PhysicalSensor sensors[2]
This implementation uses two physical sensors.
setStatus_t * queueStatus
queue status change for next regular interval
Defines control sub-system.
ARM_DRIVER_I2C Driver_I2C1_KSDK2_Blocking
KSDK handle for the I2C port defined in Driver_I2C_KSDK2.
setStatus_t * setStatus
change status indicator immediately
uint8_t sUARTOutputBuffer[256]
main output buffer defined in control.c
Definition: control.c:59
applyPerturbation_t * applyPerturbation
apply step function for testing purposes
int8_t FXAS21002_Init(PhysicalSensor *sensor, SensorFusionGlobals *sfg)
Operation is Nominal.
StatusSubsystem statusSubsystem
provides visual (usually LED) status indicator